/*jslint sloppy: true */
/*global require, FileReader, Blob */
require('./caseTest.html');
var probe = require('../global');
probe.controller('CaseTest', function ($scope, ocDialog, ocDI, Case,
								LC, Capture, $log, simulight,
								FileSaver, $location) {

	var isSuccess, $cm,
		blankCase = "#TIMES 1\n#INTERVAL 3000\n\nprocess main {\n}",
		previousLine = 0,
		bootArgs = $location.search();

	$scope['case'] = null;
	$scope.caseInstance = null;

	$scope.parse = function () {
		try {
			var sT = LC.parse($scope['case'].code);
			$scope.cmdOut('语法分析成功，可以运行或保存', 'info');
			return sT;
		} catch (e) {
			$scope.cmdOut(e.toString(), 'danger');
		}
	};

	function playerExceptionHandle(fn, actionName) {
		try {
			fn();
		} catch (error) {
			$scope.cmdOut('尝试运行测试用例失败', 'danger');
			$scope.playerStatus = 'idle';
		}
	}

	function caseRunEnd() {
		$scope.mask = false;
		$scope.caseInstance = null;
	}

	LC.setup({
		successCallback: function () {
			$scope.player.status = 'idle';
			$scope.cmdOut('本次执行成功', 'success');
			ocDialog.alert({
				title: isSuccess ? '成功' : '失败',
				message: isSuccess ? '测试用例执行成功，点击确定继续。' : '行：' +
					$scope.caseInstance.$$lastInstruction.line() + '失败',
				okFn: caseRunEnd,
				cancelFn: caseRunEnd
			}, ocDI);
		},
		runCallback: function () {
			$scope.$apply();
//			codeEmphasize(this.$);
		},
		triggerCallback: function triggerCallback(objectDOM) {
			simulight(objectDOM, $scope.LCF);
		},
		runExceptionHandle: function (CASE) {
			$scope.stop();
			isSuccess = false;
		},
		consoleFn: function (message) {
			$scope.cmdOut(message, 'primary');
		}
	});

	// Toolbar on the top.
	$scope.preSaveCase = function (callback) {
		try {
			LC.parse($scope['case'].code);
			callback();
			ocDialog.alert({
				title: '保存成功',
				message: '尝试编译并保存成功'
			}, ocDI);
		} catch (e) {
			ocDialog.alert({
				title: '分析出错',
				message: '请修复错误后再保存'
			}, ocDI);
		}
	};
	$scope.p = $scope.player = { status: 'idle' };
	$scope.buildAndPlay = function () {
		playerExceptionHandle(function () {
			$scope.caseInstance = new LC.Case($scope.parse(), {});
			// reset iframe before run
			LC.getLemoncaseFrame().src = 'about:blank';
			
			$scope.caseInstance.start();
			$scope.player.status = 'run';
			$scope.mask = true;
			isSuccess = true;
		}, '构建与启动');
	};
	$scope.pause = function () {
		playerExceptionHandle(function () {
			$scope.caseInstance.suspend();
			$scope.player.status = 'wait';
		}, '暂停测试');
	};
	$scope.stop = function () {
		playerExceptionHandle(function () {
			$scope.caseInstance.stop();
			$scope.player.status = 'idle';
			$scope.mask = false;
		}, '停止测试');
	};
	$scope.resume = function () {
		playerExceptionHandle(function () {
			$scope.caseInstance.resume();
			$scope.player.status = 'run';
		}, '继续测试');
	};
	$scope.history = window.history;
	$scope.newCase = function () {
		$scope['case'] = new Case({
			name: '未命名',
			code: blankCase
		});
	};
	$scope.createCase = function () {
		$scope['case'].$create();
	};
	$scope.openCase = function ($case) {
		$case.$get();
		$scope['case'] = $case;
		$location.search('caseId', $case.caseId);
	};
	$scope.updateCase = function () {
		$scope['case'].$modify();
	};
	$scope.uploadCode = function ($file) {
		var reader = new FileReader();
		reader.onload = function (event) {
			$scope['case'] = {
				code: event.target.result
			};

			$scope.$apply();
		};

		reader.onerror = function (event) {
			$scope.cmdOut("File could not be read! Code " + event.target.error.code, 'error');
		};

		reader.readAsText($file);
	};
	$scope.downloadCode = function () {
		var code = new Blob([$scope['case'].code], {
			type: 'text/plain;charset=utf-8'
		});
		FileSaver.saveAs(code, 'code.txt');
	};

	// Toolbar in editor panel.
	$scope.undo = function () { $cm.undo(); };
	$scope.redo = function () { $cm.redo(); };
	$scope.capture = function () {
		var e = $scope.LCF;
		e.style.backgroundColor = '#ffffff';
		Capture.setZIndex(550).setContext(e.contentWindow);

		Capture.watchHTML($scope.LCF, function (selector) {
			e.style.zIndex = 0;
			e.style.backgroundColor = '';

			//insert at current selection
			$cm.focus();
			if (!selector) { return; }
			$cm.replaceSelection('"' + selector + '"');
		});
	};
	$scope.insertField = function (fieldName) {
		$cm.replaceSelection('[' + fieldName + ']');
		$cm.focus();
	};
	$scope.insertUrl = function () {
		var l = $scope.LCF.contentWindow.location;
		$cm.replaceSelection("'" + l.href.replace(l.origin, '') + "'");
		$cm.focus();
	};

	// CSS selector editor
	$scope.cssPathEditor = {
		isActive: false,
		path: '',
		length: 0,
		capture: function (e) {
			$scope.LCF.style.backgroundColor = '#ffffff';
			Capture.setZIndex(550).setContext($scope.LCF.contentWindow);

			Capture.watchHTML($scope.LCF, function (selector) {
				$scope.LCF.style.zIndex = 0;
				$scope.LCF.style.backgroundColor = '';
				$scope.cssPathEditor.path = selector;
			});
		},
		insert: function () {
			$scope.cssPathEditor.isActive = false;
			$cm.replaceSelection("'" + $scope.cssPathEditor.path + "'");
			$cm.focus();
		},
		getLength: function (s) {
			var $d = $scope.LCF.contentWindow && $scope.LCF.contentWindow.document;
			try {
				return $d.querySelectorAll(s).length;
			} catch (e) {
				return 'Err';
			}
		}
	};
	$scope.$watch('cssPathEditor.path', function () {
		var cpi = $scope.cssPathEditor;
		cpi.length = cpi.getLength(cpi.path);
	});

	//init
    $scope.editorOptions = {
        lineWrapping : true,
        lineNumbers: true,
	    matchBrackets: true,
	    mode: "text/x-php",
	    indentWithTabs: true,
	    indentUnit: 4,
		//automatically refresh
	    autoRefresh: true,
		onLoad: function (cm) {
			$cm = cm;
			$cm.setOption('extraKeys', {
				'Ctrl-S': function () {
					var cb;
					if ($scope.bootSetup.mode === 'trial') {
						cb = $scope.downloadCode;
					} else if ($scope['case'].caseId) {
						cb = $scope.updateCase;
					} else {
						cb = $scope.createCase;
					}
					$scope.preSaveCase(cb);
				},
				'Ctrl-Q': $scope.capture
			});
		}
    };
	if (bootArgs.caseId) {
		$scope['case'] = Case.get({caseId: bootArgs.caseId});
	} else {
		$scope.newCase();
	}
});
